﻿using Cysharp.Threading.Tasks;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;

/// <summary>
/// 资源管理器
/// </summary>
public class AssetManager
{
    private static Dictionary<string, dynamic> s_Cache = new Dictionary<string, dynamic>();
    private static HashSet<string> s_LoadingKeys = new HashSet<string>();

    /// <summary>
    /// 异步加载
    /// </summary>
    public static async UniTask<T> LoadAsync<T>(string assetName) where T : Object
    {
        // 若已缓存则直接取出
        if (!s_Cache.TryGetValue(assetName, out var asset))
        {
            // 正在加载，则等待其加载完毕，再直接从缓存中读取
            if (s_LoadingKeys.Contains(assetName))
            {
                await UniTask.WaitUntil(() => !s_LoadingKeys.Contains(assetName));
                return s_Cache[assetName];
            }
            // 未缓存，则加入缓存列表，等待缓存结束后取出
            s_LoadingKeys.Add(assetName);
            asset = await Addressables.LoadAssetAsync<T>(assetName).Task;
            if (asset == null)
                return null;
            s_Cache[assetName] = asset;
            s_LoadingKeys.Remove(assetName);
        }
        return asset as T;
    }

    /// <summary>
    /// 同步加载
    /// </summary>
    public static T Load<T>(string assetName) where T : Object
    {
        // 若已缓存则直接取出
        if (!s_Cache.TryGetValue(assetName, out var asset))
        {
            asset = Addressables.LoadAssetAsync<T>(assetName).WaitForCompletion();
            if (asset == null)
                return null;
            s_Cache[assetName] = asset;
        }
        return asset as T;
    }

    public static void Release()
    {
        foreach (var asset in s_Cache.Values)
        {
            Addressables.Release(asset);
        }
        s_Cache.Clear();
    }
}